/*
 *  Copyright (C) 1998-2020 by Northwoods Software Corporation. All Rights Reserved.
 */

import * as go from 'gojs';
import { ReactDiagram } from 'gojs-react';
import * as React from 'react';

import './Diagram.scss';
import DiasmallIcon from '../../assets/diasmall.svg';
import DiabigIcon from '../../assets/diabig.svg';
// 组件图标icon
import { getStore } from 'store/store';
import { Spin, Tooltip } from 'antd';

import { makeDiagramModal } from './Diagram';
import { cloneDeep } from 'lodash';
// import { CheckOutlined, DeleteOutlined } from '@ant-design/icons';

interface DiagramProps {
  nodeDataArray: Array<go.ObjectData>;
  linkDataArray: Array<go.ObjectData>;
  modelData: go.ObjectData;
  skipsDiagramUpdate: boolean;
  /**全屏标识 */
  fixedSpan: any;
  /**版本标识 */
  versionId: number;
  // 处理双击事件
  onDiagramDbEvent: (e: go.DiagramEvent) => void;
  // 处理单击事件
  ononeDiagramDbEvent: (e: go.DiagramEvent) => void;
  /**
   * 处理所有相关的DiagramEvents，在本例中仅更改选择。
   * 在ChangedSelection上，找到相应的数据并设置selectedData状态。
   * @param e a GoJS DiagramEvent
   */
  onDiagramEvent: (e: go.DiagramEvent) => void;
  /**
   * @param obj a JSON-formatted string
   * 当拖拽组件进入图表时, 触发change事件, 将新的数据setState到数据模型中
   */
  onModelChange: (obj: go.IncrementalData) => void;
  /**
   * 处理组件高亮status
   * @param data 被修改的节点
   * @param path 被修改的属性名路径
   * @param value 新的value值
   */
  onStatusChange: (data: any, path: string, value: any) => void;
  /**
   * 处理节点修改
   * @param data 被修改的节点
   * @param value 新的value值
   */
  onNodeChange: (data: any, value: any) => void;
}

interface State {
  /**保存中... */
  saving: boolean;
  /**配置流程不正确弹框 */
  validateErrorModal: boolean;
  /**必填字段未填写组件名称 */
  validateRequired: string[];
  /**未被连接到流程的组件名称 */
  validateLink: string[];
  /**分支未被连接的分支名称 */
  validateSubLink: string[];
  /**使用了全局设置，但是没有配置全局 */
  validateGlobalSetNull: string[];
}

const timer: null | NodeJS.Timeout = null;

/**
 * 流程节点集中展示区
 * 示例： AI管理-机器人管理-版本管理-配置话术流程-流程管理-已发布【预览状态】
 */
export class DiagramWrapperView extends React.PureComponent<DiagramProps, State> {
  /**
   * Ref to keep a reference to the Diagram component, which provides access to the GoJS diagram via getDiagram().
   */
  private diagramRef: React.RefObject<ReactDiagram>;

  /** @internal */
  constructor(props: DiagramProps) {
    super(props);
    this.diagramRef = React.createRef();
    this.state = {
      // myDiagram: null,
      saving: false,
      validateErrorModal: false,
      validateRequired: [],
      validateLink: [],
      validateSubLink: [],
      validateGlobalSetNull: [],
    };
  }
  fullIcon = DiasmallIcon;
  /**
   * Get the diagram reference and add any desired diagram listeners.
   * Typically the same function will be used for each listener, with the function using a switch statement to handle the events.
   */
  public componentDidMount() {
    // console.log('DiagramWrapperView -> componentDidMount***', this);
    if (!this.diagramRef.current) return;
    const diagram = this.diagramRef.current.getDiagram();
    if (diagram instanceof go.Diagram) {
      // 监控选中事件
      diagram.addDiagramListener('ChangedSelection', this.props.onDiagramEvent);
      // 监控双击事件
      diagram.addDiagramListener('ObjectDoubleClicked', this.props.onDiagramDbEvent);
      // 监控单击事件
      diagram.addDiagramListener('ObjectSingleClicked', this.props.ononeDiagramDbEvent);
    }
  }

  componentDidUpdate() {
    // console.log('DiagramWrapperView ->update', this);
  }

  /**
   * Get the diagram reference and remove listeners that were added during mounting.
   */
  public componentWillUnmount() {
    if (!this.diagramRef.current) return;
    const diagram = this.diagramRef.current.getDiagram();
    if (diagram instanceof go.Diagram) {
      this.clearHighlightNode(diagram);
      diagram.removeDiagramListener('ChangedSelection', this.props.onDiagramEvent);
      diagram.removeDiagramListener('ObjectDoubleClicked', this.props.onDiagramDbEvent);
      diagram.removeDiagramListener('ObjectSingleClicked', this.props.ononeDiagramDbEvent);
    }
    /**清除定时器 */
    timer && clearInterval(timer);
  }

  // 取消节点高亮显示-用于重置高亮
  private clearHighlightNode(myDiagram: go.Diagram) {
    myDiagram.clearSelection();
    // 通过key找到数据模型
    const data = cloneDeep(this.props.nodeDataArray);
    if (data) {
      data.forEach(item => {
        item.status = 0;
        // myDiagram.model.updateTargetBindings(item); // 更新数据模型到图表
        if (item.category === 'ConditionComponent') {
          // 条件组件
          item.conditionArray.forEach((condition: any) => {
            condition.status = 0;
          });
        } else if (item.category === 'IntentComponent') {
          // 意图组件
          item.intentionArray.forEach((intention: any) => {
            intention.status = 0;
          });
        } else if (item.category === 'KeyComponent') {
          // 按键组件：2种显示类型
          if (item.keyFlag === 'PressKey') {
            // 按键类型
            item.pressKeyArray.forEach((data: any) => {
              data.status = 0;
            });
          } else if (item.keyFlag === 'ReceiveNumber') {
            // 收号类型
            item.receiveNumberDefaultArray.forEach((data: any) => {
              data.status = 0;
            });
          }
        } else if (item.category === 'TransferManualServiceComponent') {
          // 转人工组件
          item.transferManualIntentionArray.forEach((data: any) => {
            data.status = 0;
          });
        }
      });
      this.props.onModelChange({ modifiedNodeData: data });
    }
  }

  // 全屏操作
  private fullFlow() {
    this.props.fixedSpan('full');
    const store = getStore();
    if (store.get('isFullScreen') === true) {
      store.set('isFullScreen', false);
    } else {
      store.set('isFullScreen', true);
    }
    if (this.fullIcon === DiasmallIcon) {
      this.fullIcon = DiabigIcon;
    } else {
      this.fullIcon = DiasmallIcon;
    }
  }

  // 初始化图表
  private initDiagramModel = () => makeDiagramModal({ isView: true });

  public render() {
    return (
      <div className="diagram_container diagram_view">
        <Spin spinning={this.state.saving}>
          <ReactDiagram
            ref={this.diagramRef}
            divClassName="diagram-component"
            initDiagram={this.initDiagramModel}
            nodeDataArray={this.props.nodeDataArray}
            linkDataArray={this.props.linkDataArray}
            modelData={this.props.modelData}
            onModelChange={this.props.onModelChange}
            skipsDiagramUpdate={this.props.skipsDiagramUpdate}
          />

          <Tooltip placement="left" title="全屏">
            <div className="btn_container full_container" onClick={this.fullFlow.bind(this)}>
              <img className="btn_full" src={this.fullIcon} alt="全屏" width={20} />
            </div>
          </Tooltip>
        </Spin>
      </div>
    );
  }
}
